------------------------------------------------------------------------------- LE STRUTTURE DATI ------------------------------------------------------------------------------- La libreria gfx3d.library necessita, per un corretto funzionamento, delle seguenti strutture dati: - Polygon - Frame - Object - ShadeTable - Environment - Camera Di seguito è presente una dettagliata descrizione di ogni struttura dati ------------------ LA STRUTTURA POLYGON ------------------ Il poligono è l'unità base della grafica vettoriale. Ogni oggetto visualizzabile dalla libreria gfx3d.library è composto di poligoni. (si veda, a tal proposito, la spiegazione relativa alla struttura dati Frame) Gli attributi caratterizzanti un poligono sono: - i vertici; - il colore; - il tipo di ombreggiatura. Tutti questi attributi vengono assegnati staticamente e non è possibile quindi modificarli dinamicamente nel corso dell'esecuzione del programma. Affinchè un poligono sia visualizzabile, i vertici devono descrivere a video un percorso antiorario (si tenga presente che la libreria segue la regola della mano destra). Eventuali poligoni aventi entrambe le facce visualizzabili dovranno essere scomposti in due sottopoligoni. Una limitazione corrente della libreria consiste nel fatto che non viene eseguito alcun clipping tridimensionale a livello di poligoni, per cui, quando un vertice viene a trovarsi dietro la massima distanza focale della telecamera, il poligono intero viene scartato dalla graphics pipeline e, di conseguenza, non viene visualizzato. Per ovviare a tale inconveniente è sufficiente suddividere poligoni di grandi dimensioni in più poligoni minori. Una seconda limitazione consiste nel fatto che la libreria, attualmente, supporta solo triangoli, per cui eventuali vertici definiti dopo il terzo non vengono considerati e sono quindi scartati. Nella versione attuale della libreria, il colore è un numero da 0 a 255 identificante il colore della palette del video. Future versioni supporteranno possibilmente colori a 12 e 18 bit su Amiga AGA, 15, 16, 24 bit su scheda grafica. Nella versione attuale della libreria, il tipo di ombreggiatura può essere uno tra i seguenti: - GFX_FILL_SHADING questo valore specifica che il poligono non viene sfumato; - GFX_FLAT_SHADING questo valore specifica che il poligono viene sfumato in rapporto alla sua inclinazione rispetto la direzione di osservazione; - GFX_DEPTH_CUEING Questo valore specifica che il poligono viene sfumato in rapporto alla distanza dall'osservatore. E' possibile utilizzare il valore GFX_DEPTH_SHADING in luogo del valore GFX_DEPTH_CUEING. Per compatibilità con la versione 1.0 della libreria, ad un poligono, se non specificato precedentemente, viene associato il tipo di ombreggiatura FILL. Sono riportati di seguito i passi principali per la definizione di una struttura Polygon: GFXBegin( GFX_POLYGON ); GFXVertex( x0, y0, z0 ); GFXVertex( x1, y1, z1 ); GFXVertex( x2, y2, z2 ); GFXColor( col ); GFXShading( shade ); poly = GFXEnd() ---------------- LA STRUTTURA FRAME ---------------- Un fotogramma rappresenta quello che si deve vedere di un oggetto. Diversi oggetti possono infatti rappresentare lo stesso tipo di oggetti nel mondo reale (si pensi, ad esempio, ad una stanza con un tavolo e più sedie...). Utilizzando la struttura dati Frame, è possibile un notevole risparmio di memoria, in quanto, in presenza di più oggetti uguali, è sufficiente creare un solo fotogramma, per poi assegnarlo a tutti gli oggetti in questione. Gli attributi caratterizzanti un fotogramma sono i singoli poligoni. Come già detto nella sezione riguardante la struttura dati Polygon, il poligono è l'unità basilare della grafica vettoriale e, di conseguenza, ogni singolo fotogramma è composto di un numero variabile di poligoni. Si noti che non è possibile modificare dinamicamente una struttura Frame, in quanto si tratta di una struttura ampiamente ottimizzata. E' però possibile modificare dinamicamente il fotogramma di un oggetto. Gli oggetti che supportano questa modalità prendono il nome di "Multi Framed Objects" (MFO). Questa è infatti la seconda possibilità di utilizzo della struttura Frame, ovvero l'animazione per fotogrammi. Si consulti a questo riguardo la spiegazione relativa alla struttura dati Objects. Sono riportati di seguito i passi principali per la definizione di una struttura Frame: GFXBegin( GFX_FRAME ); GFXPolygon( poly1 ); ... GFXPolygon( polyn ); frm = GFXEnd() IMPORTANTE: Dalla versione 2.4 della GfX3d.library, ogni poligono aggiunto ad un frame viene in seguito automaticamente deallocato dalla memoria. In questo modo si ottiene, oltre ad una pressochè completa compatibilità software con gli ancora pochi programmi che sfruttano questa libreria, anche una discreta ottimizzazione nell'utilizzo dello spazio di occupazione in memoria. ----------------- LA STRUTTURA OBJECT ----------------- Un oggetto è invece un oggetto 'fisico', in quanto rappresenta un'entità esistente nella scena da rappresentare. Di un oggetto si possono specificare le coordinate nell'ambiente, la direzione che gli assi dell'oggetto formano con quelli dell'ambiente, il fotogramma appartenente all'oggetto (che cosituisce ciò che si vede dell'oggetto). È possibile modificare dinamicamente il fotogramma di un oggetto. Gli oggetti che supportano questa modalità prendono il nome di "Multi Framed Objects" (MFO). Tutti i precedenti attributi caratterizzanti l'oggetto si possono modificare dinamicamente tramite l'uso delle funzioni GFXModifyObject...() . Esistono inoltre i seguenti attributi non modificabili dinamicamente. Tali attributi specificano i piani di taglio anteriore e posteriore dell'oggetto. se un oggetto è più vicino (più lontano) del piano di taglio anteriore (posteriore), allora tale oggetto non viene disegnato a video. Un'ultima considerazione riguarda la definizione di oggetto MFO. Nella definizione di tali oggetti è necessario un accorgimento addizionale. È necessario infatti assegnare all'oggetto MFO in fase di definizione il fotogramma contenente il massimo numero di vertici e di poligoni, al fine di poter calcolare il massimo spazio riservato in memoria per l'oggetto stesso. Naturalmente, una volta definito l'oggetto, è possibile cambiare il fotogramma in questione tramite la funzione GFXModifyObjectFrame(). Sono riportati di seguito i passi principali per la definizione di una struttura Object: GFXBegin( GFX_OBJECT ); GFXPosition( x, y, z ); GFXDirection( ax, ay, az ); GFXFrame( frm ); GFXNearClip( 0 ); GFXFarClip( 65536 ); obj = GFXEnd() ---------------------- LA STRUTTURA ENVIRONMENT ---------------------- Un ambiente può essere inteso come un particolare oggetto contenente gli altri oggetti e la telecamera appartenenti alla scena. Tutte le coordinate e gli angoli di direzione delle suddette strutture dati fanno infatti riferimento agli assi di coordinate proprie dell'ambiente. Sono riportati di seguito i passi principali per la definizione di una struttura Environment: GFXBegin( GFX_ENVIRONMENT ); GFXShadeTable( table ); GFXObject( obj1 ); ... GFXObject( obj2 ); env = GFXEnd() ----------------- LA STRUTTURA CAMERA ----------------- Mediante la telecamera, l'utente finale 'vede' la scena ed ha la sensazione di esservi 'immerso'. La struttura telecamera presenta una molitudine di attributi, atti ad ottenere una perfetta visuale della scena. Tali attributi sono: - la posizione che la telecamera occupa nella scena tridimensionale; - la direzione della visuale; - la distanza focale per regolare la visione prospettica; - i fattori di scala per modificare l'aspetto della scena visualizzata; - la larghezza in pixels della visuale; - l'altezza in pixels della visuale; - il buffer video ove viene disegnata la scena visualizzata; - l'ambiente al quale fà riferimento la telecamera; - la profondità visiva della telecamera nelle scene in deep cueing. Molti di tali parametri sono modificabili dinamicamente tramite le funzioni GFXModifyCamera...() . Sono riportati di seguito i passi principali per la definizione di una struttura Camera: GFXBegin( GFX_CAMERA ); GFXEnvironment( env ); GFXPosition( x, y, z ); GFXDirection( ax, ay, az ); GFXFocus( focus ); GFXAspectRatio( rx, ry, rz ); GFXFarClip( lightdepth ); GFXWidth( 320 ); GFXHeight( 200 ); GFXVideoBuffer( raster ); obs = GFXEnd() --------------------- LA STRUTTURA SHADETABLE --------------------- La tabella delle sfumature dei colori viene utilizzata dalla libreria per calcolare il più velocemente possibile la determinata sfumatura da applicare ad un colore. Per costruire questa struttura dati, la libreria necessita del numero di passi della sfumatura, del colore verso il quale la sfumatura deve tendere, della profondità massima della sfumatura e di un array contenente tutte le 256 tonalità in uso. Il colore di destinazione viene specificato tramite la funzione GFXColor(), ed è importante notare che il colore da passare a tale funzione non rappresenta l'indice del colore all'interno dei 256 colori utilizzati, bensì rappresenta una tonalità di colore espressa in 24 bit ( 0RGB ). In questo modo, il colore di destinazione della sfumatura può anche essere assente dai 256 colori in uso. La profondità massima raggiungibile della sfumatura indica quale colore associare ad un poligono oscurato. Supponendo infatti di aver definito la seguente sfumatura in 16 passi: 0 15 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | | | | | | | | | | | | | | | | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ ^ ^ bianco nero |---------------------------------------------------------->| Senza limite di sfumatura, un poligono pienamente illuminato presenta il colore bianco, mentre un poligono privo di illuminazione viene disegnato in nero. In questo modo, però, buona parte dell'ambiente circostante può risultare non illuminata (si pensi per esempio ad un poligono perpendicolare alla direzione di vista della telecamera), quindi si avrebbe come risultato una notevole 'perdita di visibilità', dovuta ai troppi poligoni neri a schermo. Il tutto si potrebbe migliorare introducendo un minimo di illuminazione ambientale. Questo si ottiene tramite la limitazione sulla profondità di sfumatura. Introducendo infatti nell'esempio precedente una profondità massima di 12 passi: 0 11 15 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | | | | | | | | | | | | | | | | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ ^ ^ ^ bianco grigio nero |------------------------------------------>| si ottiene una sfumatura totale in 12 passi e con colori di destinazione differenti a seconda della tonalità di ogni colore. Infine, la libreria deve poter sapere su quali colori operare (ricordiamo infatti che nel modo a 256 colori non è possibile risalire alla tonalità di colore visualizzata in assenza di informazioni aggiuntive). Queste informazioni le vengono passate tramite la funzione GFXPalette(). L'argomento di tale funzione è un puntatore ad un array di 256 strutture RGB. Sono riportati di seguito i passi principali per la definizione di una struttura ShadeTable: GFXBegin( GFX_SHADETABLE ); GFX3DSteps( passi ); GFX3DThreshold( soglia ); GFX3DColor( 0rgb ); GFX3DPalette( RGBptr ); table = GFXEnd() IMPORTANTE: Nella versione attuale della libreria (GfX3d.library v2.x), non sempre le sfumature vengono calcolate esattamente. Si tratta di un effetto collaterale dovuto a precise scelte progettuali, volte a velocizzare la costruzione di una ShadeTable. Future versioni della libreria conterranno un'opzione per eseguire il calcolo preciso della tabella delle sfumature, anche se a costo di un maggior tempo di esecuzione della definizione della tabella stessa. -------------- LA STRUTTURA RGB -------------- La struttura RGB è l'unica struttura dati liberamente accessibile dall'esterno della libreria. Essa viene utilizzata per informare la libreria stessa delle tonalità di colore sulle quali operare. Gli unici parametri della struttura RGB sono le intensità di colore dei singoli componenti ( rosso, verde, blu ): struct gfx3d_RGB { uchar Red; uchar Green; uchar Blue; char paddle; } gfx3d_RGB; L'attributo paddle, per ovvie ragioni di compatibilità con le versioni future della libreria, deve essere impostato a 0. -------------------------------------------------------------------------------